package cn.com.hhrcw.service.impl;

import cn.com.hhrcw.area.service.ISysAreaService;
import cn.com.hhrcw.entity.CvResume;
import cn.com.hhrcw.entity.File;
import cn.com.hhrcw.entity.OpDeliveryHistory;
import cn.com.hhrcw.entity.OpJob;
import cn.com.hhrcw.mapper.CvResumeMapper;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.resume.ResumeHtmlUtil;
import cn.com.hhrcw.utils.resume.ResumeWordUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * <p>
 * 简历-简历 服务实现类
 * </p>
 *
 * @author jiangdong
 * @since 2020-10-29
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class CvResumeServiceImpl extends ServiceImpl<CvResumeMapper, CvResume> implements ICvResumeService {

    @Autowired
    IPiInfoService piInfoService;

    @Autowired
    ResumeWordUtil resumeWordUtil;

    @Autowired
    ResumeHtmlUtil resumeHtmlUtil;

    @Autowired
    private ICvWorkIntentionService cvWorkIntentionService;

    @Autowired
    private ICvUserWorkInfoService cvUserWorkInfoService;

    @Autowired
    private ICvUserEduInfoService cvUserEduInfoService;

    @Autowired
    private ICvProjectInfoService cvProjectInfoService;

    @Autowired
    private ICvTrainService cvTrainService;

    @Autowired
    private ICvLanguageLevelService cvLanguageLevelService;

    @Autowired
    private ICvSkillsService cvSkillsService;

    @Autowired
    private ICvCertificateService cvCertificateService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private IFileService fileService;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Autowired
    private IOpJobService opJobService;

    @Autowired
    private IOpDeliveryHistoryService opDeliveryHistoryService;

    @Autowired
    private ICvFamilyMemberService cvFamilyMemberService;

    @Autowired
    private ISysAreaService sysAreaService;

    /**
     * 根据用户的在线简历生成word文件 部分数据字典的翻译未完成
     *
     * @param userId  用户id
     * @param lanType 语种  0 中文  1英文
     * @return
     */
    @SneakyThrows
    @Override
    public String getResumeInfo(String userId, Integer lanType, String deliverJobId) {
        log.info("userId: {} lanType: {} deliverJobId: {}",userId,lanType,deliverJobId);
        CvResume cvResume = this.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId).eq(CvResume::getLanType, lanType).eq(CvResume::getType, 0).one();
        if (cvResume == null) {
            return null;
        }
        return resumeWordUtil.generateResumeWord(cvResume, lanType, deliverJobId);
    }

    @Override
    public byte[] getResumeInfo(String deliveryHistoryId, String userId) {
        return this.getResumeInfo(deliveryHistoryId, userId,0);
    }

    /**
     * 生成简历信息
     *
     * @param deliveryHistoryId 投递记录id
     * @param userId            是否生成岗位信息
     * @return java.lang.String
     */
    @Override
    public byte[] getResumeInfo(String deliveryHistoryId, String userId, int lanType) {
        XWPFTemplate template = null;
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            CvResume resume = null;
            String adjustFlag = "无";
            //String adjustFlag = "/";
            String jobName = "";
            if (StrUtil.isNotBlank(deliveryHistoryId)) {
                OpDeliveryHistory history = this.opDeliveryHistoryService.getById(deliveryHistoryId);
                OpJob job = this.opJobService.getById(history.getJobId());
                resume = this.getById(history.getResumeId());
                jobName = job.getJobName();
                adjustFlag = Optional.ofNullable(history).map(OpDeliveryHistory::getR10).map(e -> StrUtil.equals(e, "1") ? "是" : "否").orElse(resume.getLanType() == 0 ? "无" : "None");
            } else if (StrUtil.isNotBlank(userId)) {
                resume = this.lambdaQuery()
                    .eq(CvResume::getDelFlag, 0)
                    .eq(CvResume::getUserId, userId)
                    .eq(CvResume::getLanType, lanType)
                    .eq(CvResume::getType, 0)
                    .one();
            }
            if (resume == null) {
                return null;
            }
            if (resume.getLanType() == 0) {
                resumeWordUtil.generateResumeWord(resume, resume.getLanType(), null);
            }
            if (resume.getLanType() == 1) {
                resumeWordUtil.generateResumeWord(resume, resume.getLanType(), null);
            }
            String path = resume.getLanType() == 0 ? resume.getWordPath() : resume.getWordPathEn();
            HashMap<Object, Object> params = new HashMap<>(2);
            params.put("adjustFlag", adjustFlag);
            params.put("jobName", jobName);

            template = XWPFTemplate.compile(path).render(params);
            template.write(bos);
            return bos.toByteArray();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        } finally {
            IoUtil.close(template);
        }
    }

    @Override
    public List<byte[]> getMultipleResumeInfo(String deliveryHistoryId, String userId) {
        List<CvResume> resumes = new ArrayList<>();
        String adjustFlag = "无";
        //String adjustFlag = "/";
        String jobName = "";
        String dir = "";
        try {
            if (StrUtil.isNotBlank(deliveryHistoryId)) {
                OpDeliveryHistory history = this.opDeliveryHistoryService.getById(deliveryHistoryId);
                OpJob job = this.opJobService.getById(history.getJobId());
                CvResume resume = this.getById(history.getResumeId());
                resumes.add(resume);
                jobName = job.getJobName();
                adjustFlag = Optional.ofNullable(history).map(OpDeliveryHistory::getR10).map(e -> StrUtil.equals(e, "1") ? "是" : "否").orElse(resume.getLanType() == 0 ? "无" : "None");
            } else if (StrUtil.isNotBlank(userId)) {
                resumes = this.lambdaQuery()
                    .eq(CvResume::getDelFlag, 0)
                    .eq(CvResume::getUserId, userId)
                    .orderByDesc(CvResume::getId)
                    .list();
            }
            if (CollUtil.isEmpty(resumes)) {
                return null;
            }
            List<byte[]> bytes = new ArrayList<>();
            for (CvResume resume : resumes) {
                if (StrUtil.isBlank(resume.getWordPath()) && resume.getLanType() == 0) {
                    resumeWordUtil.generateResumeWord(resume, resume.getLanType(), null);
                }
                if (StrUtil.isBlank(resume.getWordPathEn()) && resume.getLanType() == 1) {
                    resumeWordUtil.generateResumeWord(resume, resume.getLanType(), null);
                }
                //缓存文件名的字节数组
                byte[] b2 = new byte[512];
                StringBuilder fileName = new StringBuilder(dir);
                //附件简历
                if (resume.getType() == 1 && StrUtil.isNotBlank(resume.getFileId())) {
                    File file = fileService.getById(resume.getFileId());
                    if (!FileUtil.exist(file.getFilePath())) {
                        continue;
                    }
                    byte[] name = fileName.append(resume.getResumeName()).append(file.getFileLastName()).toString().getBytes(StandardCharsets.UTF_8);
                    System.arraycopy(name, 0, b2, 0, name.length);

                    byte[] readBytes = FileUtil.readBytes(file.getFilePath());
                    //前512位为文件名
                    byte[] merge = ArrayUtil.addAll(b2, readBytes);
                    bytes.add(merge);
                    continue;
                }
                byte[] name = fileName.append(resume.getResumeName()).append(".docx").toString().getBytes(StandardCharsets.UTF_8);
                System.arraycopy(name, 0, b2, 0, name.length);

                String path = resume.getLanType() == 0 ? resume.getWordPath() : resume.getWordPathEn();
                HashMap<Object, Object> params = new HashMap<>(2);
                params.put("adjustFlag", adjustFlag);
                params.put("jobName", jobName);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                XWPFTemplate template = XWPFTemplate.compile(path).render(params);
                template.writeAndClose(bos);
                //前512位为文件名
                byte[] merge = ArrayUtil.addAll(b2, bos.toByteArray());
                bytes.add(merge);
            }
            return bytes;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    public static void main(String[] args) {
        byte[] b1 = "黄河人才网的个人简历.docx".getBytes(StandardCharsets.UTF_8);
        byte[] b2 = new byte[512];
        byte[] b3 = "6666666".getBytes(StandardCharsets.UTF_8);
        System.arraycopy(b1, 0, b2, 0, b1.length);
        byte[] bytes = ArrayUtil.addAll(b2, b3);
        System.out.println(new String(ArrayUtil.sub(bytes, 512, bytes.length)));
    }

    @SneakyThrows
    @Override
    public String getResumeInfoPDF(String userId, Integer lanType, String jobId) {
        return resumeHtmlUtil.generateResumeHtml(userId, lanType, jobId);
    }

    @Override
    public List<CvResume> getByDate(Date beginDate, Date endDate){
        LambdaQueryWrapper<CvResume> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.between(CvResume::getCreateTime,beginDate,endDate).or().between(CvResume::getUpdateTime,beginDate,endDate);
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public CvResume getByUserId(String userId, Integer lanType,Integer type,Integer resumeType){
        return this.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId).eq(CvResume::getLanType, lanType).eq(CvResume::getType, type).eq(CvResume::getResumeType,resumeType).one();
    }
}
